package acme.bloodtime.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import modelo.ICiudadDO;
import modelo.IPropiedadDO;
import modelo.IPropiedadVampiroDAO;
import modelo.IPropiedadVampiroDO;
import modelo.IVampiroDO;
import dao.api.DataObject;
import dao.api.Reference;

/**
 * 
 * @author Armando G. Lozada N.
 * 
 */
public class PropiedadVampiroDAO extends BloodTimeBaseDAO implements IPropiedadVampiroDAO {

    public PropiedadVampiroDAO() {
        // Empty
    }

    @Override
    public void createTable() throws SQLException {
        StringBuffer strbuf;

        // ----------------------------------------

        dropTable();

        // ----------------------------------------
        VampiroDAO vampiroDAO = new VampiroDAO();
        PropiedadDAO propiedadDAO = new PropiedadDAO();
        CiudadDAO ciudadDAO = new CiudadDAO();

        strbuf = new StringBuffer();

        strbuf.append("CREATE TABLE ");
        strbuf.append(getTableName());
        strbuf.append(" (");
        strbuf.append(PropiedadVampiroDO.ID);
        strbuf.append(" SERIAL PRIMARY KEY, ");
        strbuf.append(PropiedadVampiroDO.VAMPIRO_ID);
        strbuf.append(" INT REFERENCES ");
        strbuf.append(vampiroDAO.getTableName());
        strbuf.append(" NOT NULL, ");
        strbuf.append(PropiedadVampiroDO.PROPIEDAD_ID);
        strbuf.append(" INT REFERENCES ");
        strbuf.append(propiedadDAO.getTableName());
        strbuf.append(" NOT NULL, ");
        strbuf.append(PropiedadVampiroDO.CIUDAD_ID);
        strbuf.append(" INT REFERENCES ");
        strbuf.append(ciudadDAO.getTableName());
        strbuf.append(" NOT NULL, ");
        strbuf.append(PropiedadVampiroDO.NOMBRE);
        strbuf.append(" VARCHAR(15),    ");
        strbuf.append(PropiedadVampiroDO.NUM_ESCLAVOS);
        strbuf.append(" INT,");
        strbuf.append(PropiedadVampiroDO.HABILITADO);
        strbuf.append(" BOOLEAN ");

        strbuf.append(")");

        System.err.println(strbuf.toString());

        connection.createStatement().execute(strbuf.toString());
    }

    @Override
    public void delete(DataObject dataObject) throws SQLException {
        internalDelete(dataObject, PropiedadVampiroDO.class);

    }

    // ------------------------------------------------------------------------
    @Override
    public void insert(DataObject dataObject) throws SQLException {
        checkCache(dataObject, CHECK_INSERT);
        checkClass(dataObject, PropiedadVampiroDO.class, CHECK_INSERT);

        PropiedadVampiroDO propiedadVampiroDO = (PropiedadVampiroDO) dataObject;

        propiedadVampiroDO.setId(getNextId());

        StringBuffer strbuf = new StringBuffer();

        strbuf.append("INSERT INTO ");
        strbuf.append(getTableName());
        strbuf.append(" VALUES (");
        strbuf.append(propiedadVampiroDO.getId());
        strbuf.append(", ");
        /* PILAS */

        // ---------------------------------
        // Setting the Reference to Vampiro
        // ---------------------------------

        Reference<IVampiroDO> vampiroRef = propiedadVampiroDO.getVampiroId();
        vampiroRef.checkInsert();

        strbuf.append(vampiroRef.getIdAsString());
        strbuf.append(", ");

        // ---------------------------------
        // Setting the Reference to Propiedad
        // ---------------------------------

        Reference<IPropiedadDO> propiedadRef = propiedadVampiroDO.getPropiedadId();
        propiedadRef.checkInsert();

        strbuf.append(propiedadRef.getIdAsString());
        strbuf.append(", ");

        // ---------------------------------
        // Setting the Reference to Ciudad
        // ---------------------------------

        Reference<ICiudadDO> ciudadRef = propiedadVampiroDO.getCiudadId();
        ciudadRef.checkInsert();

        strbuf.append(ciudadRef.getIdAsString());
        strbuf.append(", ");

        strbuf.append(singleQuotes(propiedadVampiroDO.getNombre()));
        strbuf.append(", ");

        strbuf.append(propiedadVampiroDO.getNumEsclavos());
        strbuf.append(", ");

        strbuf.append(propiedadVampiroDO.isHabilitado());

        strbuf.append(")");

        System.err.println(strbuf.toString());

        connection.createStatement().executeUpdate(strbuf.toString());

        dtaSession.add(dataObject);

    }

    @Override
    public void update(DataObject dataObject) throws SQLException {
        checkCache(dataObject, CHECK_UPDATE);
        checkClass(dataObject, PropiedadVampiroDO.class, CHECK_UPDATE);

        PropiedadVampiroDO propiedadVampiroDO = (PropiedadVampiroDO) dataObject;

        StringBuffer strbuf = new StringBuffer();
        strbuf.append("UPDATE ");
        strbuf.append(getTableName());
        strbuf.append(" SET ");

        // ---------------------------------
        // Setting the Reference to Vampiro
        // ---------------------------------

        Reference<IVampiroDO> vampiroRef = propiedadVampiroDO.getVampiroId();
        vampiroRef.checkUpdate();

        strbuf.append(PropiedadVampiroDO.VAMPIRO_ID);
        strbuf.append(" = ");
        strbuf.append(vampiroRef.getIdAsString());
        strbuf.append(", ");

        // ---------------------------------
        // Setting the Reference to Propiedad
        // ---------------------------------

        Reference<IPropiedadDO> propiedadRef = propiedadVampiroDO.getPropiedadId();
        propiedadRef.checkUpdate();

        strbuf.append(PropiedadVampiroDO.PROPIEDAD_ID);
        strbuf.append(" = ");
        strbuf.append(propiedadRef.getIdAsString());
        strbuf.append(", ");

        // ---------------------------------
        // Setting the Reference to Ciudad
        // ---------------------------------

        Reference<ICiudadDO> ciudadRef = propiedadVampiroDO.getCiudadId();
        ciudadRef.checkUpdate();

        strbuf.append(PropiedadVampiroDO.CIUDAD_ID);
        strbuf.append(" = ");
        strbuf.append(ciudadRef.getIdAsString());
        strbuf.append(", ");

        strbuf.append(PropiedadVampiroDO.NUM_ESCLAVOS);
        strbuf.append(" = ");
        strbuf.append(propiedadVampiroDO.getNumEsclavos());
        strbuf.append(", ");

        strbuf.append(PropiedadVampiroDO.HABILITADO);
        strbuf.append(" = ");
        strbuf.append(propiedadVampiroDO.isHabilitado());

        strbuf.append(" WHERE ");
        strbuf.append(PropiedadVampiroDO.ID);
        strbuf.append(" = ");
        strbuf.append(propiedadVampiroDO.getId());

        System.err.println(strbuf.toString());
        connection.createStatement().executeUpdate(strbuf.toString());
    }

    public List<IPropiedadVampiroDO> listByVampiroId(int vampiroId) throws SQLException {
        StringBuffer strbuf = new StringBuffer();

        strbuf.append("SELECT ");
        strbuf.append("*");
        strbuf.append(" FROM ");
        strbuf.append(getTableName());
        strbuf.append(" WHERE ");
        strbuf.append(PropiedadVampiroDO.VAMPIRO_ID);
        strbuf.append(" = ");
        strbuf.append(vampiroId);

        System.err.println(strbuf.toString());

        ResultSet rs = //
        connection.createStatement().executeQuery(strbuf.toString());

        List<IPropiedadVampiroDO> ret = new ArrayList<IPropiedadVampiroDO>();

        while (rs.next()) {
            ret.add(resultSetToDO(rs));
        }

        return ret;
    }

    public List<IPropiedadVampiroDO> listByCiudadId(int ciudadId) throws SQLException {
        StringBuffer strbuf = new StringBuffer();

        strbuf.append("SELECT ");
        strbuf.append("*");
        strbuf.append(" FROM ");
        strbuf.append(getTableName());
        strbuf.append(" WHERE ");
        strbuf.append(PropiedadVampiroDO.CIUDAD_ID);
        strbuf.append(" = ");
        strbuf.append(ciudadId);

        System.err.println(strbuf.toString());

        ResultSet rs = //
        connection.createStatement().executeQuery(strbuf.toString());

        List<IPropiedadVampiroDO> ret = new ArrayList<IPropiedadVampiroDO>();

        while (rs.next()) {
            ret.add(resultSetToDO(rs));
        }

        return ret;
    }

    public void loadVampiroRef(IPropiedadVampiroDO propiedadVampiroDO) throws SQLException {
        checkClass(propiedadVampiroDO, PropiedadVampiroDO.class, CHECK_UPDATE);

        VampiroDAO vampiroDAO = new VampiroDAO();
        vampiroDAO.init(connectionBean);

        Reference<IVampiroDO> ref = propiedadVampiroDO.getVampiroId();

        // ----------------------------------------
        // If ident == 0 there is nothing to do
        // ----------------------------------------

        if (ref.getRefIdent() == 0) {
            return;
        }

        VampiroDO vampiroDO = //
        (VampiroDO) vampiroDAO.loadById(ref.getRefIdent());

        ref.setRefValue(vampiroDO);
    }

    public void loadPropiedadRef(IPropiedadVampiroDO propiedadVampiroDO) throws SQLException {
        checkClass(propiedadVampiroDO, PropiedadVampiroDO.class, CHECK_UPDATE);

        PropiedadDAO propiedadDAO = new PropiedadDAO();
        propiedadDAO.init(connectionBean);

        Reference<IPropiedadDO> ref = propiedadVampiroDO.getPropiedadId();

        // ----------------------------------------
        // If ident == 0 there is nothing to do
        // ----------------------------------------

        if (ref.getRefIdent() == 0) {
            return;
        }

        PropiedadDO propiedadDO = //
        (PropiedadDO) propiedadDAO.loadById(ref.getRefIdent());

        ref.setRefValue(propiedadDO);
    }

    public void loadCiudadRef(IPropiedadVampiroDO propiedadVampiroDO) throws SQLException {
        checkClass(propiedadVampiroDO, PropiedadVampiroDO.class, CHECK_UPDATE);

        CiudadDAO ciudadDAO = new CiudadDAO();
        ciudadDAO.init(connectionBean);

        Reference<ICiudadDO> ref = propiedadVampiroDO.getCiudadId();

        // ----------------------------------------
        // If ident == 0 there is nothing to do
        // ----------------------------------------

        if (ref.getRefIdent() == 0) {
            return;
        }

        CiudadDO ciudadDO = //
        (CiudadDO) ciudadDAO.loadById(ref.getRefIdent());

        ref.setRefValue(ciudadDO);
    }

    @Override
    protected PropiedadVampiroDO resultSetToDO(ResultSet rs) throws SQLException {
        PropiedadVampiroDO ret = //
        (PropiedadVampiroDO) dtaSession.getDtaByKey( //
                PropiedadVampiroDO.class, rs.getInt(PropiedadVampiroDO.ID));

        if (ret != null) {
            return ret;
        }

        ret = new PropiedadVampiroDO();

        ret.setId/*                 */(rs.getInt(PropiedadVampiroDO.ID));
        ret.setNombre/*             */(rs.getString(PropiedadVampiroDO.NOMBRE));
        ret.setNumEsclavos/*        */(rs.getInt(PropiedadVampiroDO.NUM_ESCLAVOS));
        ret.setHabilitado/*         */(rs.getBoolean(PropiedadVampiroDO.HABILITADO));

        // ----------------------------
        // Setting the reference id's
        // ----------------------------

        // Propiedad Reference

        Reference<IPropiedadDO> propiedadRef = new Reference<IPropiedadDO>();
        propiedadRef.setRefIdent(rs.getInt(PropiedadVampiroDO.PROPIEDAD_ID));

        ret.setPropiedadId(propiedadRef);

        // Ciudad Reference

        Reference<ICiudadDO> ciudadRef = new Reference<ICiudadDO>();
        ciudadRef.setRefIdent(rs.getInt(PropiedadVampiroDO.CIUDAD_ID));

        ret.setCiudadId(ciudadRef);

        // Vampiro Reference

        Reference<IVampiroDO> vampiroRef = new Reference<IVampiroDO>();
        vampiroRef.setRefIdent(rs.getInt(PropiedadVampiroDO.VAMPIRO_ID));

        ret.setVampiroId(vampiroRef);

        return (PropiedadVampiroDO) dtaSession.add(ret);
    }

    @Override
    public List<IPropiedadVampiroDO> listByPropiedadId(int propiedadId) throws SQLException {
        StringBuffer strbuf = new StringBuffer();

        strbuf.append("SELECT ");
        strbuf.append("*");
        strbuf.append(" FROM ");
        strbuf.append(getTableName());
        strbuf.append(" WHERE ");
        strbuf.append(PropiedadVampiroDO.PROPIEDAD_ID);
        strbuf.append(" = ");
        strbuf.append(propiedadId);

        System.err.println(strbuf.toString());

        ResultSet rs = //
        connection.createStatement().executeQuery(strbuf.toString());

        List<IPropiedadVampiroDO> ret = new ArrayList<IPropiedadVampiroDO>();

        while (rs.next()) {
            ret.add(resultSetToDO(rs));
        }

        return ret;
    }

}
